﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using WeShare.WeiXin.Common.EnumKey;
#if !NET40
using System.Threading.Tasks;
#endif
namespace WeShare.WeiXin.Common
{
    public class OpenApi
    {
        /// <summary>
        /// 使用redis缓存
        /// </summary>
        public static bool IsUseRedisCache { get; private set; }
        /// <summary>
        /// 生成access_token时的错误回调。
        /// </summary>
        public Action<string> ErrorAction { get; set; }
        public OpenApi(IRedisClient _redis = null,Action<string> errorAction=null)
        {
            this.ErrorAction = errorAction;
            if (_redis != null)
            {
                redis = _redis;
                IsUseRedisCache = true;

            }
        }
        /// <summary>
        /// 微信平台开发者模式参数列表
        /// </summary>
        private static List<ApiConfig> apiConfigs;
        /// <summary>
        /// 微信支付商户信息列表
        /// </summary>
        private static List<PayConfig> payConfigs;
        public static IRedisClient redis;
        /// <summary>
        /// 注册接口信息，支持多公众号
        /// </summary>
        /// <param name="config"></param>
        public void Register(params ApiConfig[] config)
        {
            if (config != null && config.Any())
            {
                apiConfigs = config.Distinct(new ApiConfigComparer()).ToList();
                new Thread(() =>
                {
                    foreach (var item in apiConfigs)
                    {
                        AccessToken.GetValue(item.AppId, item.Platform,this.ErrorAction);
                    }
                }).Start();
            }
        }
#if !NET40
        public async void RegisterAsync(params ApiConfig[] config)
        {
            if (config != null && config.Any())
            {
                apiConfigs = config.Distinct(new ApiConfigComparer()).ToList();
                foreach (var item in apiConfigs)
                {
                    await AccessToken.GetValueAsync(item.AppId, item.Platform, this.ErrorAction);
                }
            }
        }
        public static async Task<string> GetTokenAsync(string tokenOrAppId = "", PlatformType platform = PlatformType.Mp)
        {
            if (string.IsNullOrEmpty(tokenOrAppId) || tokenOrAppId.Length < 25)
            {
                return await AccessToken.GetValueAsync(tokenOrAppId, platform);
            }
            else
            {
                return tokenOrAppId;
            }

        }
#endif


        /// <summary>
        /// 注册支付接口相关参数
        /// </summary>
        /// <param name="configs"></param>
        public void RegisterPay(params PayConfig[] configs)
        {
            payConfigs = configs.ToList();
        }
        /// <summary>
        /// 获取支付相关参数
        /// </summary>
        /// <param name="mchId"></param>
        /// <returns></returns>
        public static PayConfig GetPayConfig(string mchId = "")
        {
            if (string.IsNullOrEmpty(mchId) && payConfigs?.Count > 0)
            {
                return payConfigs[0];
            }
            if (payConfigs == null)
            {
                throw new Exception("未设置支付相关参数");
            }
            return payConfigs.FirstOrDefault(p => p.MchId == mchId);
        }
        /// <summary>
        /// 根据appid，获取对应的接口参数信息
        /// </summary>
        /// <param name="appid"></param>
        /// <returns></returns>
        public static ApiConfig GetConfig(string appid = "", PlatformType platform = PlatformType.Mp)
        {
            if (string.IsNullOrEmpty(appid) && apiConfigs?.Count > 0)
            {
                return apiConfigs.FirstOrDefault(a => a.Platform == platform);
            }
            return apiConfigs.FirstOrDefault(a => a.AppId == appid);
        }
        /// <summary>
        /// 根据accesstoken或者appid获取accesstoken
        /// </summary>
        /// <param name="tokenOrAppId"></param>
        /// <returns></returns>
        public static string GetToken(string tokenOrAppId = "", PlatformType platform = PlatformType.Mp)
        {
            if (string.IsNullOrEmpty(tokenOrAppId) || tokenOrAppId.Length < 25)
            {
                return AccessToken.GetValue(tokenOrAppId, platform);
            }
            else
            {
                return tokenOrAppId;
            }

        }
        private class ApiConfigComparer : IEqualityComparer<ApiConfig>
        {
            public bool Equals(ApiConfig x, ApiConfig y)
            {
                return x.AppId == y.AppId;
            }
            public int GetHashCode(ApiConfig obj)
            {
                return obj.AppId.GetHashCode();
            }
        }
    }

}
